package Huffman;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class HuffmanTest {
    public static void main(String[] args) throws IOException {
        File file = new File("英文文件.txt");
        File file1 = new File("编码文件.txt");
        File file2 = new File("解码文件.txt");

        if (!file1.exists() && !file2.exists())
        {
            file1.createNewFile();
            file2.createNewFile();
        }
        FileReader fileReader = new FileReader(file);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        FileWriter fileWriter1 = new FileWriter(file1);
        FileWriter fileWriter2 = new FileWriter(file2);

        int temp = 0, sum = 0;

        String neirong = "";
        String string1 = "",string2 = "";

        List<HuffmanNode> list = new ArrayList<HuffmanNode>();
        List<String> list1 = new ArrayList<String>();
        List<String> list2 = new ArrayList<String>();
        List<HuffmanNode<String>> list3 = new ArrayList<HuffmanNode<String>>();
        List<String> list4 = new ArrayList<String>();

        list1.add("a");
        list1.add("b");
        list1.add("c");
        list1.add("d");
        list1.add("e");
        list1.add("f");
        list1.add("g");
        list1.add("h");
        list1.add("i");
        list1.add("j");
        list1.add("k");
        list1.add("l");
        list1.add("m");
        list1.add("n");
        list1.add("o");
        list1.add("p");
        list1.add("q");
        list1.add("r");
        list1.add("s");
        list1.add("t");
        list1.add("u");
        list1.add("v");
        list1.add("w");
        list1.add("x");
        list1.add("y");
        list1.add("z");
        list1.add(" ");
        list1.add(".");
        list1.add(",");


        int[] Esum = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        for(int a = 0; a <= getFileLineCount(file); a++){
            String tp = bufferedReader.readLine();
            neirong += tp;
            for(int b = 0; b < tp.length(); b++){
                    list2.add(String.valueOf(tp.charAt(b)));
            }
            Esum[0] += Collections.frequency(list2, list1.get(0));
            Esum[1] += Collections.frequency(list2, list1.get(1));
            Esum[2] += Collections.frequency(list2, list1.get(2));
            Esum[3] += Collections.frequency(list2, list1.get(3));
            Esum[4] += Collections.frequency(list2, list1.get(4));
            Esum[5] += Collections.frequency(list2, list1.get(5));
            Esum[6] += Collections.frequency(list2, list1.get(6));
            Esum[7] += Collections.frequency(list2, list1.get(7));
            Esum[8] += Collections.frequency(list2, list1.get(8));
            Esum[9] += Collections.frequency(list2, list1.get(9));
            Esum[10] += Collections.frequency(list2, list1.get(10));
            Esum[11] += Collections.frequency(list2, list1.get(11));
            Esum[12] += Collections.frequency(list2, list1.get(12));
            Esum[13] += Collections.frequency(list2, list1.get(13));
            Esum[14] += Collections.frequency(list2, list1.get(14));
            Esum[15] += Collections.frequency(list2, list1.get(15));
            Esum[16] += Collections.frequency(list2, list1.get(16));
            Esum[17] += Collections.frequency(list2, list1.get(17));
            Esum[18] += Collections.frequency(list2, list1.get(18));
            Esum[19] += Collections.frequency(list2, list1.get(19));
            Esum[20] += Collections.frequency(list2, list1.get(20));
            Esum[21] += Collections.frequency(list2, list1.get(21));
            Esum[22] += Collections.frequency(list2, list1.get(22));
            Esum[23] += Collections.frequency(list2, list1.get(23));
            Esum[24] += Collections.frequency(list2, list1.get(24));
            Esum[25] += Collections.frequency(list2, list1.get(25));
            Esum[26] += Collections.frequency(list2, list1.get(26));
            Esum[27] += Collections.frequency(list2, list1.get(27));
            Esum[28] += Collections.frequency(list2, list1.get(28));
        }


        for(int c = 0; c < Esum.length; c++)
            sum += Esum[c];
        System.out.println("总字母个数：" + sum);

        for(int d = 0; d< Esum.length; d++){
            System.out.println(list1.get(d)+" 重复次数："+Esum[d]+ " 概率：" +(double)Esum[d]/sum);
            list.add(new HuffmanNode<String>(list1.get(d),Esum[d]));
        }
        Collections.sort(list);
        HuffmanTree huffmanTree = new HuffmanTree();
        HuffmanNode<String> node = huffmanTree.createTree(list);
        list3 = huffmanTree.breath(node);

        String[] letter = new String[Esum.length];
        String[] code = new String[Esum.length];

        for(int e = 0;e<list3.size();e++){
            if(list3.get(e).getLetter() != null){
                System.out.println(list3.get(e).getLetter()+"的编码为"+list3.get(e).getCode()+" ");
                letter[temp] = list3.get(e).getLetter();
                code[temp] = list3.get(e).getCode();
                temp++;
            }
        }

        String result = "";
        for(int f = 0; f < sum; f++){
            for(int j = 0;j<letter.length;j++){
                if(neirong.charAt(f) == letter[j].charAt(0))
                    result += code[j];
            }
        }

        System.out.println("编码后："+ result);

        for(int i = 0;i<result.length();i++){
            list4.add(result.charAt(i)+"");
        }


        for(int h = list4.size(); h > 0; h--){
            string1 = string1 + list4.get(0);
            list4.remove(0);
            for(int i=0;i<code.length;i++){
                if (string1.equals(code[i])) {
                    string2 = string2+""+letter[i];
                    string1 = "";
                }
            }
        }
        System.out.println("解码后：" + string2);

        fileWriter1.write(result);
        fileWriter2.write(string2);
        fileWriter1.close();
        fileWriter2.close();
    }

    //读取文件行数
    private static int getFileLineCount(File file) {
        int cnt = 0;
        InputStream is = null;
        try {
            is = new BufferedInputStream(new FileInputStream(file));
            byte[] c = new byte[1024];
            int readChars = 0;
            while ((readChars = is.read(c)) != -1) {
                for (int i = 0; i < readChars; ++i) {
                    if (c[i] == '\n') {
                        ++cnt;
                    }
                }
            }
        } catch (Exception ex) {
            cnt = -1;
            ex.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return cnt;
    }
}
